/*
board-games:	An educational framework for board games programming.
    Copyright (C) 2008  Daniel Gutson, FuDePAN

    This file is part of board-games.

    board-games is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    board-games is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <iostream>
#include "common_sdk/board.h"


int SharedBoard::share_create(size_t boardId)
{
    if (state == Disconnected)
    {
        key_t k = ftok("/tmp_sharings", int(boardId));
        shmid = shmget(k, size(), IPC_CREAT | 0777);
        if (shmid != -1)
        {
            //attach now:

            void* const shmaddr = shmat(shmid, NULL /*get_mem()*/, /*SHM_RND*/ 0); // check!
            if (shmaddr == (void*)(-1))
                throw "Error attaching to created board sharing";
            else
            {
                copy_to(shmaddr);
                remap(shmaddr);
                state = ConnectedMaster;
            }
        }
        else
            throw "Error creating board sharing";

    }

    return shmid;
}

void SharedBoard::share_connect(int shmid)
{
    state = ConnectedSlave;
    this->shmid = shmid;
    void* const shmaddr = shmat(shmid, NULL /*get_mem()*/, SHM_RDONLY);
    /*
    key_t k = ftok("/tmp_sharings", 1);
    shmid = shmget(k, size(), 0);
    if (shmid == -1)
        throw "CACA!";
        */

    //void* const shmaddr = shmat(shmid, NULL /*get_mem()*/, SHM_RDONLY);
    if (shmaddr == (void*)(-1))
        throw "Error connecting to board";
    else
        remap(shmaddr);

}

void SharedBoard::share_destroy()
{
    if (state != Disconnected)
    {
        int ret;
        ret = shmdt(get_mem());
        if (ret == -1)
            throw "Error dettaching from board";

        if (state == ConnectedMaster)
        {
            ret = shmctl(shmid, IPC_RMID, NULL);
            if (ret == -1)
                throw "Error removing board sharing";
        }
    }

    state = Disconnected;
}

